import { useState, useCallback } from 'react';

interface UseDownloadOptions {
  filename?: string;
  onProgress?: (percent: number) => void;
  onSuccess?: () => void;
  onError?: (err: any) => void;
}

export function useDownload() {
  const [downloading, setDownloading] = useState(false);

  const download = useCallback(
    async (urlOrBlob: string | Blob, options: UseDownloadOptions = {}) => {
      const { filename = 'download', onProgress, onSuccess, onError } = options;
      setDownloading(true);

      try {
        let blob: Blob;

        if (typeof urlOrBlob === 'string') {
          const response = await fetch(urlOrBlob);
          if (!response.ok) throw new Error('Download failed');

          const contentLength = response.headers.get('Content-Length');
          const total = contentLength ? parseInt(contentLength, 10) : 0;

          const reader = response.body?.getReader();
          const chunks: Uint8Array[] = [];
          let received = 0;

          if (reader) {
            while (true) {
              const { done, value } = await reader.read();
              if (done) break;
              if (value) {
                chunks.push(value);
                received += value.length;
                if (onProgress && total) {
                  onProgress(Math.round((received / total) * 100));
                }
              }
            }
            blob = new Blob(chunks);
          } else {
            blob = await response.blob();
          }
        } else {
          blob = urlOrBlob;
        }

        const blobUrl = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = blobUrl;
        a.download = filename;
        a.style.display = 'none';
        document.body.appendChild(a);
        a.click();
        a.remove();
        URL.revokeObjectURL(blobUrl);
        onSuccess?.();
      } catch (err) {
        onError?.(err);
        console.error('Download error:', err);
      } finally {
        setDownloading(false);
      }
    },
    []
  );

  return { download, downloading };
}
